home *** CD-ROM | disk | FTP | other *** search
/ SGI Developer Toolbox 6.1 / SGI Developer Toolbox 6.1 - Disc 4.iso / public / bit / src / forms / FORMS / symbols.c < prev    next >
C/C++ Source or Header  |  1994-08-01  |  8KB  |  278 lines

  1. /*
  2.  * symbols.c
  3.  *
  4.  * This file is part of the basis of the Forms Library
  5.  *
  6.  * It contains the routine that draws all the symbols like arrows, etc.
  7.  * instead of labels. It can easily be extended with new symbols.
  8.  *
  9.  * Written by Mark Overmars
  10.  *
  11.  * Version 2.1 a
  12.  * Date: Oct  2, 1992
  13.  */
  14.  
  15. #include <stdio.h>
  16. #include <string.h>
  17. #include "gl/gl.h"
  18. #include "forms.h"
  19.  
  20. typedef struct {
  21.   char name[15];        /* its name */
  22.   void (*drawit)(int);  /* the drawing routine */
  23.   int scalable;        /* whether symbol can be scaled */
  24.   int empty;            /* whether entry is used already */
  25. } SYMBOL;
  26.  
  27. #define MAXSYMBOL       211
  28.    /* Maximal number of symbols in table. Only half of them are
  29.       used. Should be prime. */
  30.  
  31. static SYMBOL symbols[MAXSYMBOL];      /* The symbols */
  32. static int symbnumb = -1;              /* Their number */
  33.  
  34. static int h1(char name[])
  35. /* The first hash function. */
  36. {
  37.   if (name[0] == '\0') return 0;
  38.   else if (name[1] == '\0') return name[0] % MAXSYMBOL;
  39.   else if (name[2] == '\0') return (31*name[0]+name[1]) % MAXSYMBOL;
  40.   else return (71*name[0]+31*name[1]+name[2]) % MAXSYMBOL;
  41. }
  42.  
  43. static int h2(char name[])
  44. /* The second hash function. */
  45. {
  46.   if (name[0] == '\0') return 0;
  47.   else if (name[1] == '\0') return (3*name[0]) % MAXSYMBOL;
  48.   else return (51*name[0]+3*name[1]) % MAXSYMBOL;
  49. }
  50.  
  51. static int find(char name[])
  52. /* Returns the index for the name or -1. */
  53. {
  54.   int pos = h1(name), hh2 = h2(name);
  55.   while (strcmp(symbols[pos].name,name) != 0 && ! symbols[pos].empty)
  56.     pos = (pos + hh2) % MAXSYMBOL;
  57.   if (symbols[pos].empty) return -1; else return pos;
  58. }
  59.  
  60. static int find_empty(char name[])
  61. /* Returns the first empty index for the name (-1 when name exists). */
  62. {
  63.   int pos = h1(name), hh2 = h2(name);
  64.   while (strcmp(symbols[pos].name,name) != 0 && ! symbols[pos].empty)
  65.     pos = (pos + hh2) % MAXSYMBOL;
  66.   if (symbols[pos].empty) return pos; else return -1;
  67. }
  68.  
  69. /**************** The routines seen by the user *************************/
  70.  
  71. int fl_add_symbol(char name[], FL_DRAWPTR drawit, int scalable)
  72. /* Adds a symbol to the system. Returns whether correct. */
  73. {
  74.   int pos;
  75.   pos = find_empty(name);
  76.   if (pos == -1 || symbnumb > MAXSYMBOL / 2)
  77.     {fl_error("fl_add_symbol","Cannot add another symbol."); return FALSE;}
  78.   strcpy(symbols[pos].name,name);
  79.   symbols[pos].drawit = drawit;
  80.   symbols[pos].empty = FALSE;
  81.   symbols[pos].scalable = scalable;
  82.   symbnumb++;
  83.   return TRUE;
  84. }
  85.  
  86. int fl_draw_symbol(char label[],float x,float y,float w,float h, int col)
  87. /* Draws the symbol with the given label, returns whether it exists */
  88. {
  89.   int pos , i, shift;
  90.   char str[50];
  91.   int rotangle = 0;
  92.   int equalscale = 0;
  93.   if (label[0] != '@') return FALSE;
  94.   if (label[1] == '#') {equalscale = 1; pos = 2;} else pos = 1;
  95.   shift = pos;
  96.   if (label[pos] >= '1' && label[pos] <= '9')
  97.   {
  98.     switch (label[pos])
  99.     {
  100.     case '9': rotangle =  450; break;
  101.     case '8': rotangle =  900; break;
  102.     case '7': rotangle = 1350; break;
  103.     case '4': rotangle = 1800; break;
  104.     case '1': rotangle = 2250; break;
  105.     case '2': rotangle = 2700; break;
  106.     case '3': rotangle = 3150; break;
  107.     }
  108.     shift = pos+1;
  109.   }
  110.   else if (label[pos] == '0')
  111.   {
  112.     rotangle = 1000*(label[pos+1]-'0') + 100*(label[pos+2]-'0') +
  113.             10*(label[pos+3]-'0');
  114.     shift = pos+4;
  115.   }
  116.   i = 0;
  117.   do str[i] = label[i+shift]; while (str[i++] != NULL);
  118.   pos = find(str);
  119.   if (pos == -1) return FALSE;
  120.   pushmatrix();
  121.   translate(x+w/2.0,y+h/2.0,0.0);
  122.   if (symbols[pos].scalable)
  123.   {
  124.     if (equalscale)
  125.       { if (w<h) scale(0.4*w,0.4*w,1.0); else scale(0.4*h,0.4*h,1.0); }
  126.     else
  127.       scale(0.4*w,0.4*h,1.0);
  128.     rotate(rotangle,'z');
  129.   }
  130.   (symbols[pos].drawit)(col);
  131.   popmatrix();
  132.   return TRUE;
  133. }
  134.  
  135. /******************** THE DEFAULT SYMBOLS ****************************/
  136.  
  137. /* Some help stuff */
  138.  
  139. #define BP bgnpolygon()
  140. #define EP endpolygon()
  141. #define BL bgnline();
  142. #define EL endline();
  143. #define BC bgnclosedline();
  144. #define EC endclosedline();
  145.  
  146. static void circle(float x,float y,float r,int c)
  147.   { fl_color(c); circf(x,y,r); fl_color(BLACK); circ(x,y,r); }
  148.  
  149. static void rectangle(float x1,float y1,float x2,float y2,int c)
  150.   { fl_color(c); rectf(x1,y1,x2,y2); fl_color(BLACK); rect(x1,y1,x2,y2); }
  151.  
  152. static void vv(float x,float y)
  153.   { float v[2] ; v[0] = x; v[1] = y; v2f(v);}
  154.  
  155. /* The drawing routines */
  156.  
  157. static void draw_arrow1(int col)
  158. {
  159.   fl_color(col);
  160.   BP; vv(-0.8,-0.4); vv(-0.8,0.4); vv(0.3,0.4); vv(0.3,-0.4); EP;
  161.   BP; vv(0.0,0.8); vv(0.8,0.0); vv(0.0,-0.8); EP;
  162.   fl_color(BLACK);
  163.   BC; vv(-0.8,-0.4); vv(-0.8,0.4); vv(0.0,0.4); vv(0.0,0.8); vv(0.8,0.0);
  164.       vv(0.0,-0.8); vv(0.0,-0.4); EC;
  165. }
  166.  
  167. static void draw_arrow2(int col)
  168. {
  169.   fl_color(col);
  170.   BP; vv(-0.20,0.7); vv(0.50,0.0); vv(-0.20,-0.7); EP;
  171.   fl_color(BLACK);
  172.   BC; vv(-0.20,0.7); vv(0.50,0.0); vv(-0.20,-0.7); EC;
  173. }
  174.  
  175. static void draw_arrow3(int col)
  176. {
  177.   fl_color(col);
  178.   BP; vv(0.15,0.7); vv(0.85,0.0); vv(0.15,-0.7); EP;
  179.   BP; vv(-0.55,0.7); vv(0.15,0.0); vv(-0.55,-0.7); EP;
  180.   fl_color(BLACK);
  181.   BC; vv(0.15,0.7); vv(0.85,0.0); vv(0.15,-0.7); EC;
  182.   BC; vv(-0.55,0.7); vv(0.15,0.0); vv(-0.55,-0.7); EC;
  183. }
  184.  
  185. static void draw_arrow01(int col)
  186.   { rotate(1800,'z'); draw_arrow1(col); }
  187.  
  188. static void draw_arrow02(int col)
  189.   { rotate(1800,'z'); draw_arrow2(col); }
  190.  
  191. static void draw_arrow03(int col)
  192.   { rotate(1800,'z'); draw_arrow3(col); }
  193.  
  194. static void draw_doublearrow(int col)
  195. {
  196.   fl_color(col);
  197.   BP; vv(-0.35,-0.4); vv(-0.35,0.4); vv(0.35,0.4); vv(0.35,-0.4); EP;
  198.   BP; vv(0.25,0.8); vv(0.85,0.0); vv(0.25,-0.8); EP;
  199.   BP; vv(-0.25,0.8); vv(-0.85,0.0); vv(-0.25,-0.8); EP;
  200.   fl_color(BLACK);
  201.   BC; vv(-0.25,0.4); vv(0.25,0.4); vv(0.25,0.8); vv(0.85,0.0);
  202.       vv(0.25,-0.8); vv(0.25,-0.4); vv(-0.25,-0.4); vv(-0.25,-0.8);
  203.       vv(-0.85,0.0); vv(-0.25,0.8); EC;
  204. }
  205.  
  206. static void draw_arrow(int col)
  207. {
  208.   fl_color(col);
  209.   BP; vv(0.65,0.1); vv(1.0,0.0); vv(0.65,-0.1); EP;
  210.   fl_color(BLACK);
  211.   BL; vv(-1.0,0.0); vv(0.65,0.0); EL;
  212.   BC; vv(0.65,0.1); vv(1.0,0.0); vv(0.65,-0.1); EC;
  213. }
  214.  
  215. static void draw_returnarrow(int col)
  216. {
  217.   fl_color(col);
  218.   BP; vv(-0.8,0.0); vv(-0.1,0.7); vv(-0.1,-0.7); EP;
  219.   fl_color(BLACK);
  220.   BC; vv(-0.8,0.0); vv(-0.1,0.7); vv(-0.1,-0.7); EC;
  221.   BL; vv(-0.1,0.0); vv(0.8,0.0); vv(0.8,0.7); EL;
  222. }
  223.  
  224. static void draw_square(int col)
  225.   { rectangle(-0.7,-0.7,0.7,0.7,col); }
  226.  
  227. static void draw_circle(int col)
  228.   { circle(0.0,0.0,0.7,col); }
  229.  
  230. static void draw_line(int col)
  231.   { fl_color(col); BL; vv(-1.0,0.0); vv(1.0,0.0); EL; }
  232.  
  233. static void draw_plus(int col)
  234. {
  235.   fl_color(col);
  236.   BP; vv(-0.9,-0.15); vv(-0.9,0.15); vv(0.9,0.15); vv(0.9,-0.15); EP;
  237.   BP; vv(-0.15,-0.9); vv(-0.15,0.9); vv(0.15,0.9); vv(0.15,-0.9); EP;
  238.   fl_color(BLACK);
  239.   BC;
  240.   vv(-0.9,-0.15); vv(-0.9,0.15); vv(-0.15,0.15); vv(-0.15,0.9);
  241.   vv(0.15,0.9); vv(0.15,0.15); vv(0.9,0.15); vv(0.9,-0.15);
  242.   vv(0.15,-0.15); vv(0.15,-0.9); vv(-0.15,-0.9); vv(-0.15,-0.15);
  243.   EC;
  244. }
  245.  
  246. static void draw_menu(int col)
  247. {
  248.   fl_color(FL_RIGHT_BOUND_COL);
  249.   rectf(-0.5, -1.0, 0.8, 0.1);
  250.   rectf(-0.5, 0.45, 0.8, 0.85);
  251.   rectangle(-0.65, -0.85, 0.65, 0.25, col);
  252.   rectangle(-0.65, 0.6, 0.65, 1.0, col);
  253. }
  254.  
  255. void fl_init_symbols()
  256. /* initialises all the symbol entries and adds the default symbols */
  257. {
  258.   int i;
  259.   symbnumb = 0;
  260.   for (i=0; i<MAXSYMBOL; i++) symbols[i].empty = TRUE;
  261.  
  262.   fl_add_symbol("",                draw_arrow1,      1);  
  263.   fl_add_symbol("->",              draw_arrow1,      1);
  264.   fl_add_symbol(">",               draw_arrow2,      1);
  265.   fl_add_symbol(">>",              draw_arrow3,      1);
  266.   fl_add_symbol("<-",              draw_arrow01,     1);
  267.   fl_add_symbol("<",               draw_arrow02,     1);
  268.   fl_add_symbol("<<",              draw_arrow03,     1);
  269.   fl_add_symbol("<->",             draw_doublearrow, 1);
  270.   fl_add_symbol("arrow",           draw_arrow,       1);  
  271.   fl_add_symbol("returnarrow",     draw_returnarrow, 1);  
  272.   fl_add_symbol("square",          draw_square,      1);
  273.   fl_add_symbol("circle",          draw_circle,      1);
  274.   fl_add_symbol("line",            draw_line,        1);
  275.   fl_add_symbol("plus",            draw_plus,        1);
  276.   fl_add_symbol("menu",           draw_menu,         1);
  277. }
  278.